package biz.almas.uycnr.crawler.crawler.handler;

import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

import biz.almas.uycnr.crawler.entity.Appendix;
import biz.almas.uycnr.crawler.entity.CnrDocument;
import biz.almas.uycnr.crawler.utils.CnrValidator;
import biz.almas.uycnr.crawler.utils.HtmlUtil;

/**
 * @Description:
 * @Copyright: Copyright (c) 2015 XinJiang Almas Software All Rights Reserved
 * @Company: XinJiang Almas Software
 * @author Ansar786 Nov 19, 2015
 * @version V1.0
 * @history:
 * 
 */
public class DocumentXmlHandler extends DefaultHandler {
	// 存储正在解析的元素的数据
	private Map<String, String> map = new HashMap<String, String>();

	private List<CnrDocument> documents = new ArrayList<CnrDocument>();

	private List<Appendix> appendixs = new ArrayList<Appendix>();
	
	public int langId;
	// 开始解析的元素
	private final String NODE_NAME = "Document";
	// 正在解析的元素的名字
	private String currentTag = null;
	// 正在解析的元素的元素值
	private String currentValue = null;

	private long beginTime;
	private long endTime;

	// 定义日志输出对象
	private static Logger logger = Logger.getLogger(DocumentXmlHandler.class);

	/**
	 * 
	 */
	public DocumentXmlHandler() {
		super();
	}

	/**
	 * 解析文档开始
	 */
	public void startDocument() throws SAXException {
		logger.info("开始解析XML数据");
		beginTime = System.currentTimeMillis();
	}

	/**
	 * 解析文档结束
	 */
	public void endDocument() throws SAXException {
		endTime = System.currentTimeMillis();
		logger.info("结束解析XML数据结束，共耗时" + (endTime - beginTime) + "毫秒");
	}

	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		currentTag = qName;
		if (NODE_NAME.equals(currentTag)) {
			map.clear();
		}
	}

	public void characters(char[] ch, int start, int length)
			throws SAXException {
		if (currentTag != null && map != null) {
			currentValue = new String(ch, start, length);
			// 如果内容不为空和空格，也不是换行符则将该元素名和值和存入map中
			if (currentValue != null && !currentValue.trim().equals("")
					&& !currentValue.trim().equals("\n")) {
				map.put(currentTag.trim(), currentValue.trim());
			}
			// 当前的元素已解析过，将其置空用于下一个元素的解析
			currentTag = null;
			currentValue = null;
		}

	}

	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		if (NODE_NAME.equals(qName)) {
			addList();
		}
		if ("FILE".equals(qName)) {
			addAppandixToList();
		}
	}

	private void addList() {
		try {
			CnrDocument document = new CnrDocument();
			document.setDocId(CnrValidator.parseInt(map.get("DOCID"), "文档编号有误"));
			document.setSiteId(CnrValidator.parseInt(map.get("SITEID")));
			document.setDocChannel(CnrValidator.parseInt(map.get("DOCCHANNEL"),
					"文档所属栏目编号有误"));
			document.setDocAuthor(map.get("DOCAUTHOR"));
			document.setDocSource(map.get("DOCSOURCE"));
			document.setDocKeyWords(map.get("DOCKEYWORDS"));
			document.setCruser(map.get("CRUSER"));
			document.setOperUser(map.get("OPERUSER"));
			document.setDocEditor(map.get("DOCEDITOR"));
			document.setDocType(CnrValidator.parseInt(map.get("DOCTYPE")));
			document.setDocStatus(CnrValidator.parseInt(map.get("DOCSTATUS")));
			document.setAttachPic(CnrValidator.parseInt(map.get("ATTACHPIC")));
			document.setDocTitle(CnrValidator.parseString(map.get("DOCTITLE"),
					"文档标题不能为空！"));
			document.setDocContent(map.get("DOCCONTENT"));
			document.setDocHtmlCon(map.get("DOCHTMLCON"));
			document.setDocHtmlContent(HtmlUtil.removeHtmlTag(map
					.get("DOCHTMLCON")));
			document.setDocPubHtmlCon(map.get("DOCPUBHTMLCON"));
			document.setDocWordsCount(CnrValidator.parseInt(map
					.get("DOCWORDSCOUNT")));
			document.setDocFirstPubTime(CnrValidator.string2DateTime(map
					.get("DOCFIRSTPUBTIME")));
			document.setDocPubTime(CnrValidator.string2DateTime(map
					.get("DOCPUBTIME")));
			document.setDocRelTime(CnrValidator.string2DateTime(map
					.get("DOCRELTIME")));
			document.setCrtime(CnrValidator.string2DateTime(map.get("CRTIME")));
			document.setOperTime(CnrValidator.string2DateTime(map
					.get("OPERTIME")));
			document.setDocKind(CnrValidator.parseInt(map.get("DOCKIND")));
			document.setDocOutUpId(CnrValidator.parseInt(map.get("DOCOUTUPID")));
			document.setLangId(langId);
			document.setStatus(1);
			documents.add(document);
		} catch (ParseException e) {
			logger.error("解析文档是出错：" + e.toString() + "\t" + map.get("DOCID")
					+ "\t" + map.get("DOCTITLE"));
		}
	}

	private void addAppandixToList() {
		try {
			Appendix appendix = new Appendix();
			appendix.setDocId(CnrValidator.parseInt(map.get("DOCID"),
					"附件所属文档编号有误！"));
			appendix.setAppendixId(CnrValidator.parseInt(map.get("APPENDIXID"),
					"没有或附件编号有误！"));
			appendix.setAppFile(map.get("APPFILE"));
			appendix.setAppFileType(CnrValidator.parseInt(map
					.get("APPFILETYPE")));
			appendix.setAppDesc(map.get("APPDESC"));
			appendix.setAppLinkAlt(map.get("APPLINKALT"));
			appendix.setAppSern(CnrValidator.parseInt((map.get("APPSERN"))));
			appendix.setAppTime(CnrValidator.string2DateTime(map.get("APPTIME")));
			appendix.setCrtime(CnrValidator.string2DateTime(map.get("CRTIME")));
			appendix.setFileUrl(CnrValidator.parseString(map.get("FILEURL"),
					"文件url不能为空！"));
			appendix.setFileExt(map.get("FILEEXT"));
			appendix.setAppAutor(map.get("APPAUTHOR"));

			appendixs.add(appendix);
		} catch (ParseException e) {
			// logger.error("解析文档附件是出错：" + e.toString());
		}
	}

	public List<CnrDocument> getDocuments() {
		return documents;
	}

	public List<Appendix> getAppendixs() {
		return appendixs;
	}

	public InputSource resolveEntity(String publicId, String systemId)
			throws IOException, SAXException {
		return super.resolveEntity(publicId, systemId);
	}

	public void notationDecl(String name, String publicId, String systemId)
			throws SAXException {
		super.notationDecl(name, publicId, systemId);
	}

	public void unparsedEntityDecl(String name, String publicId,
			String systemId, String notationName) throws SAXException {
		super.unparsedEntityDecl(name, publicId, systemId, notationName);
	}

	public void setDocumentLocator(Locator locator) {
		super.setDocumentLocator(locator);
	}

	public void startPrefixMapping(String prefix, String uri)
			throws SAXException {
		super.startPrefixMapping(prefix, uri);
	}

	public void endPrefixMapping(String prefix) throws SAXException {
		super.endPrefixMapping(prefix);
	}

	public void ignorableWhitespace(char[] ch, int start, int length)
			throws SAXException {
		super.ignorableWhitespace(ch, start, length);
	}

	public void processingInstruction(String target, String data)
			throws SAXException {
		super.processingInstruction(target, data);
	}

	public void skippedEntity(String name) throws SAXException {
		super.skippedEntity(name);
	}

	public void warning(SAXParseException e) throws SAXException {
		super.warning(e);
	}

	public void error(SAXParseException e) throws SAXException {
		super.error(e);
	}

	public void fatalError(SAXParseException e) throws SAXException {
		super.fatalError(e);
	}
}
